package org.apache.commons.httpclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.util.IdleConnectionHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MultiThreadedHttpConnectionManager
  implements HttpConnectionManager
{
  private static WeakHashMap ALL_CONNECTION_MANAGERS;
  public static final int DEFAULT_MAX_HOST_CONNECTIONS = 2;
  public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20;
  private static final Log LOG;
  private static final ReferenceQueue REFERENCE_QUEUE;
  private static ReferenceQueueThread REFERENCE_QUEUE_THREAD;
  private static final Map REFERENCE_TO_CONNECTION_SOURCE;
  static Class class$org$apache$commons$httpclient$MultiThreadedHttpConnectionManager;
  private ConnectionPool connectionPool = new ConnectionPool(null);
  private HttpConnectionManagerParams params = new HttpConnectionManagerParams();
  private volatile boolean shutdown = false;

  static
  {
    Class localClass;
    if (class$org$apache$commons$httpclient$MultiThreadedHttpConnectionManager == null)
    {
      localClass = class$("org.apache.commons.httpclient.MultiThreadedHttpConnectionManager");
      class$org$apache$commons$httpclient$MultiThreadedHttpConnectionManager = localClass;
    }
    while (true)
    {
      LOG = LogFactory.getLog(localClass);
      REFERENCE_TO_CONNECTION_SOURCE = new HashMap();
      REFERENCE_QUEUE = new ReferenceQueue();
      ALL_CONNECTION_MANAGERS = new WeakHashMap();
      return;
      localClass = class$org$apache$commons$httpclient$MultiThreadedHttpConnectionManager;
    }
  }

  public MultiThreadedHttpConnectionManager()
  {
    synchronized (ALL_CONNECTION_MANAGERS)
    {
      ALL_CONNECTION_MANAGERS.put(this, null);
      return;
    }
  }

  static Class class$(String paramString)
  {
    try
    {
      Class localClass = Class.forName(paramString);
      return localClass;
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }

  private HostConfiguration configurationForConnection(HttpConnection paramHttpConnection)
  {
    HostConfiguration localHostConfiguration = new HostConfiguration();
    localHostConfiguration.setHost(paramHttpConnection.getHost(), paramHttpConnection.getPort(), paramHttpConnection.getProtocol());
    if (paramHttpConnection.getLocalAddress() != null)
      localHostConfiguration.setLocalAddress(paramHttpConnection.getLocalAddress());
    if (paramHttpConnection.getProxyHost() != null)
      localHostConfiguration.setProxy(paramHttpConnection.getProxyHost(), paramHttpConnection.getProxyPort());
    return localHostConfiguration;
  }

  private HttpConnection doGetConnection(HostConfiguration paramHostConfiguration, long paramLong)
    throws ConnectionPoolTimeoutException
  {
    Object localObject1 = null;
    int i = this.params.getMaxConnectionsPerHost(paramHostConfiguration);
    int j = this.params.getMaxTotalConnections();
    HostConfiguration localHostConfiguration;
    HostConnectionPool localHostConnectionPool;
    int k;
    label65: label89: Object localObject4;
    Object localObject10;
    Object localObject6;
    Object localObject9;
    synchronized (this.connectionPool)
    {
      localHostConfiguration = new HostConfiguration(paramHostConfiguration);
      while (true)
      {
        try
        {
          localHostConnectionPool = this.connectionPool.getHostPool(localHostConfiguration, true);
          if (paramLong > 0L)
          {
            k = 1;
            break label592:
            if (localObject1 != null)
              break label563;
            throw new IllegalStateException("Connection factory has been shutdown.");
          }
        }
        finally
        {
          monitorexit;
        }
        k = 0;
        break label592:
        if (localHostConnectionPool.freeConnections.size() > 0)
          localObject1 = this.connectionPool.getFreeConnection(localHostConfiguration);
        if ((localHostConnectionPool.numConnections < i) && (this.connectionPool.numConnections < j))
          localObject1 = this.connectionPool.createConnection(localHostConfiguration);
        if ((localHostConnectionPool.numConnections >= i) || (this.connectionPool.freeConnections.size() <= 0))
          break;
        this.connectionPool.deleteLeastUsedConnection();
        HttpConnection localHttpConnection = this.connectionPool.createConnection(localHostConfiguration);
        localObject1 = localHttpConnection;
      }
      label399: label563: label592: label242: if ((k == 0) || (localObject4 > 0L));
    }
  }

  private static void removeReferenceToConnection(HttpConnectionWithReference paramHttpConnectionWithReference)
  {
    synchronized (REFERENCE_TO_CONNECTION_SOURCE)
    {
      REFERENCE_TO_CONNECTION_SOURCE.remove(paramHttpConnectionWithReference.reference);
      return;
    }
  }

  public static void shutdownAll()
  {
    while (true)
    {
      int i;
      synchronized (REFERENCE_TO_CONNECTION_SOURCE)
      {
        synchronized (ALL_CONNECTION_MANAGERS)
        {
          MultiThreadedHttpConnectionManager[] arrayOfMultiThreadedHttpConnectionManager = (MultiThreadedHttpConnectionManager[])(MultiThreadedHttpConnectionManager[])ALL_CONNECTION_MANAGERS.keySet().toArray(new MultiThreadedHttpConnectionManager[ALL_CONNECTION_MANAGERS.size()]);
          i = 0;
          if (i < arrayOfMultiThreadedHttpConnectionManager.length)
          {
            if (arrayOfMultiThreadedHttpConnectionManager[i] == null)
              break label109;
            arrayOfMultiThreadedHttpConnectionManager[i].shutdown();
            break label109:
          }
          if (REFERENCE_QUEUE_THREAD != null)
          {
            REFERENCE_QUEUE_THREAD.shutdown();
            REFERENCE_QUEUE_THREAD = null;
          }
          REFERENCE_TO_CONNECTION_SOURCE.clear();
          return;
        }
      }
      label109: ++i;
    }
  }

  // ERROR //
  private static void shutdownCheckedOutConnections(ConnectionPool paramConnectionPool)
  {
    // Byte code:
    //   0: new 358	java/util/ArrayList
    //   3: dup
    //   4: invokespecial 359	java/util/ArrayList:<init>	()V
    //   7: astore_1
    //   8: getstatic 77	org/apache/commons/httpclient/MultiThreadedHttpConnectionManager:REFERENCE_TO_CONNECTION_SOURCE	Ljava/util/Map;
    //   11: astore_2
    //   12: aload_2
    //   13: monitorenter
    //   14: getstatic 77	org/apache/commons/httpclient/MultiThreadedHttpConnectionManager:REFERENCE_TO_CONNECTION_SOURCE	Ljava/util/Map;
    //   17: invokeinterface 360 1 0
    //   22: invokeinterface 364 1 0
    //   27: astore 4
    //   29: aload 4
    //   31: invokeinterface 369 1 0
    //   36: ifeq +72 -> 108
    //   39: aload 4
    //   41: invokeinterface 373 1 0
    //   46: checkcast 375	java/lang/ref/Reference
    //   49: astore 7
    //   51: getstatic 77	org/apache/commons/httpclient/MultiThreadedHttpConnectionManager:REFERENCE_TO_CONNECTION_SOURCE	Ljava/util/Map;
    //   54: aload 7
    //   56: invokeinterface 378 2 0
    //   61: checkcast 13	org/apache/commons/httpclient/MultiThreadedHttpConnectionManager$ConnectionSource
    //   64: getfield 379	org/apache/commons/httpclient/MultiThreadedHttpConnectionManager$ConnectionSource:connectionPool	Lorg/apache/commons/httpclient/MultiThreadedHttpConnectionManager$ConnectionPool;
    //   67: aload_0
    //   68: if_acmpne -39 -> 29
    //   71: aload 4
    //   73: invokeinterface 381 1 0
    //   78: aload 7
    //   80: invokevirtual 383	java/lang/ref/Reference:get	()Ljava/lang/Object;
    //   83: checkcast 156	org/apache/commons/httpclient/HttpConnection
    //   86: astore 8
    //   88: aload 8
    //   90: ifnull -61 -> 29
    //   93: aload_1
    //   94: aload 8
    //   96: invokevirtual 386	java/util/ArrayList:add	(Ljava/lang/Object;)Z
    //   99: pop
    //   100: goto -71 -> 29
    //   103: astore_3
    //   104: aload_2
    //   105: monitorexit
    //   106: aload_3
    //   107: athrow
    //   108: aload_2
    //   109: monitorexit
    //   110: aload_1
    //   111: invokevirtual 387	java/util/ArrayList:iterator	()Ljava/util/Iterator;
    //   114: astore 5
    //   116: aload 5
    //   118: invokeinterface 369 1 0
    //   123: ifeq +34 -> 157
    //   126: aload 5
    //   128: invokeinterface 373 1 0
    //   133: checkcast 156	org/apache/commons/httpclient/HttpConnection
    //   136: astore 6
    //   138: aload 6
    //   140: invokevirtual 390	org/apache/commons/httpclient/HttpConnection:close	()V
    //   143: aload 6
    //   145: aconst_null
    //   146: invokevirtual 394	org/apache/commons/httpclient/HttpConnection:setHttpConnectionManager	(Lorg/apache/commons/httpclient/HttpConnectionManager;)V
    //   149: aload 6
    //   151: invokevirtual 397	org/apache/commons/httpclient/HttpConnection:releaseConnection	()V
    //   154: goto -38 -> 116
    //   157: return
    //
    // Exception table:
    //   from	to	target	type
    //   14	106	103	finally
    //   108	110	103	finally
  }

  private static void storeReferenceToConnection(HttpConnectionWithReference paramHttpConnectionWithReference, HostConfiguration paramHostConfiguration, ConnectionPool paramConnectionPool)
  {
    ConnectionSource localConnectionSource = new ConnectionSource(null);
    localConnectionSource.connectionPool = paramConnectionPool;
    localConnectionSource.hostConfiguration = paramHostConfiguration;
    synchronized (REFERENCE_TO_CONNECTION_SOURCE)
    {
      if (REFERENCE_QUEUE_THREAD == null)
      {
        REFERENCE_QUEUE_THREAD = new ReferenceQueueThread();
        REFERENCE_QUEUE_THREAD.start();
      }
      REFERENCE_TO_CONNECTION_SOURCE.put(paramHttpConnectionWithReference.reference, localConnectionSource);
      return;
    }
  }

  public void closeIdleConnections(long paramLong)
  {
    this.connectionPool.closeIdleConnections(paramLong);
    deleteClosedConnections();
  }

  public void deleteClosedConnections()
  {
    this.connectionPool.deleteClosedConnections();
  }

  public HttpConnection getConnection(HostConfiguration paramHostConfiguration)
  {
    try
    {
      HttpConnection localHttpConnection = getConnectionWithTimeout(paramHostConfiguration, 0L);
      return localHttpConnection;
    }
    catch (ConnectionPoolTimeoutException localConnectionPoolTimeoutException)
    {
      LOG.debug("Unexpected exception while waiting for connection", localConnectionPoolTimeoutException);
    }
  }

  public HttpConnection getConnection(HostConfiguration paramHostConfiguration, long paramLong)
    throws HttpException
  {
    LOG.trace("enter HttpConnectionManager.getConnection(HostConfiguration, long)");
    try
    {
      HttpConnection localHttpConnection = getConnectionWithTimeout(paramHostConfiguration, paramLong);
      return localHttpConnection;
    }
    catch (ConnectionPoolTimeoutException localConnectionPoolTimeoutException)
    {
      throw new HttpException(localConnectionPoolTimeoutException.getMessage());
    }
  }

  public HttpConnection getConnectionWithTimeout(HostConfiguration paramHostConfiguration, long paramLong)
    throws ConnectionPoolTimeoutException
  {
    LOG.trace("enter HttpConnectionManager.getConnectionWithTimeout(HostConfiguration, long)");
    if (paramHostConfiguration == null)
      throw new IllegalArgumentException("hostConfiguration is null");
    if (LOG.isDebugEnabled())
      LOG.debug("HttpConnectionManager.getConnection:  config = " + paramHostConfiguration + ", timeout = " + paramLong);
    return new HttpConnectionAdapter(doGetConnection(paramHostConfiguration, paramLong));
  }

  public int getConnectionsInPool()
  {
    synchronized (this.connectionPool)
    {
      int i = this.connectionPool.numConnections;
      return i;
    }
  }

  public int getConnectionsInPool(HostConfiguration paramHostConfiguration)
  {
    while (true)
    {
      synchronized (this.connectionPool)
      {
        HostConnectionPool localHostConnectionPool = this.connectionPool.getHostPool(paramHostConfiguration, false);
        if (localHostConnectionPool == null)
          break label40;
        i = localHostConnectionPool.numConnections;
        return i;
      }
      label40: int i = 0;
    }
  }

  public int getConnectionsInUse()
  {
    return getConnectionsInPool();
  }

  public int getConnectionsInUse(HostConfiguration paramHostConfiguration)
  {
    return getConnectionsInPool(paramHostConfiguration);
  }

  public int getMaxConnectionsPerHost()
  {
    return this.params.getDefaultMaxConnectionsPerHost();
  }

  public int getMaxTotalConnections()
  {
    return this.params.getMaxTotalConnections();
  }

  public HttpConnectionManagerParams getParams()
  {
    return this.params;
  }

  public boolean isConnectionStaleCheckingEnabled()
  {
    return this.params.isStaleCheckingEnabled();
  }

  public void releaseConnection(HttpConnection paramHttpConnection)
  {
    LOG.trace("enter HttpConnectionManager.releaseConnection(HttpConnection)");
    if (paramHttpConnection instanceof HttpConnectionAdapter)
      paramHttpConnection = ((HttpConnectionAdapter)paramHttpConnection).getWrappedConnection();
    SimpleHttpConnectionManager.finishLastResponse(paramHttpConnection);
    this.connectionPool.freeConnection(paramHttpConnection);
  }

  public void setConnectionStaleCheckingEnabled(boolean paramBoolean)
  {
    this.params.setStaleCheckingEnabled(paramBoolean);
  }

  public void setMaxConnectionsPerHost(int paramInt)
  {
    this.params.setDefaultMaxConnectionsPerHost(paramInt);
  }

  public void setMaxTotalConnections(int paramInt)
  {
    this.params.setMaxTotalConnections(paramInt);
  }

  public void setParams(HttpConnectionManagerParams paramHttpConnectionManagerParams)
  {
    if (paramHttpConnectionManagerParams == null)
      throw new IllegalArgumentException("Parameters may not be null");
    this.params = paramHttpConnectionManagerParams;
  }

  public void shutdown()
  {
    monitorenter;
    try
    {
      synchronized (this.connectionPool)
      {
        if (!(this.shutdown))
        {
          this.shutdown = true;
          this.connectionPool.shutdown();
        }
        return;
      }
    }
    finally
    {
      monitorexit;
    }
  }

  private class ConnectionPool
  {
    private LinkedList freeConnections;
    private IdleConnectionHandler idleConnectionHandler;
    private final Map mapHosts;
    private int numConnections;
    private final MultiThreadedHttpConnectionManager this$0;
    private LinkedList waitingThreads;

    private ConnectionPool()
    {
      this.this$0 = this$1;
      this.freeConnections = new LinkedList();
      this.waitingThreads = new LinkedList();
      this.mapHosts = new HashMap();
      this.idleConnectionHandler = new IdleConnectionHandler();
      this.numConnections = 0;
    }

    ConnectionPool(MultiThreadedHttpConnectionManager.1 param1)
    {
      this(this$1);
    }

    private void deleteConnection(HttpConnection paramHttpConnection)
    {
      monitorenter;
      try
      {
        HostConfiguration localHostConfiguration = this.this$0.configurationForConnection(paramHttpConnection);
        if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
          MultiThreadedHttpConnectionManager.LOG.debug("Reclaiming connection, hostConfig=" + localHostConfiguration);
        paramHttpConnection.close();
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = getHostPool(localHostConfiguration, true);
        localHostConnectionPool.freeConnections.remove(paramHttpConnection);
        localHostConnectionPool.numConnections -= 1;
        this.numConnections -= 1;
        if ((localHostConnectionPool.numConnections == 0) && (localHostConnectionPool.waitingThreads.isEmpty()))
          this.mapHosts.remove(localHostConfiguration);
        this.idleConnectionHandler.remove(paramHttpConnection);
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public void closeIdleConnections(long paramLong)
    {
      monitorenter;
      try
      {
        this.idleConnectionHandler.closeIdleConnections(paramLong);
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public HttpConnection createConnection(HostConfiguration paramHostConfiguration)
    {
      monitorenter;
      try
      {
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = getHostPool(paramHostConfiguration, true);
        if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
          MultiThreadedHttpConnectionManager.LOG.debug("Allocating new connection, hostConfig=" + paramHostConfiguration);
        MultiThreadedHttpConnectionManager.HttpConnectionWithReference localHttpConnectionWithReference = new MultiThreadedHttpConnectionManager.HttpConnectionWithReference(paramHostConfiguration);
        localHttpConnectionWithReference.getParams().setDefaults(this.this$0.params);
        localHttpConnectionWithReference.setHttpConnectionManager(this.this$0);
        this.numConnections = (1 + this.numConnections);
        localHostConnectionPool.numConnections = (1 + localHostConnectionPool.numConnections);
        MultiThreadedHttpConnectionManager.access$900(localHttpConnectionWithReference, paramHostConfiguration, this);
        monitorexit;
        return localHttpConnectionWithReference;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public void deleteClosedConnections()
    {
      monitorenter;
      try
      {
        Iterator localIterator = this.freeConnections.iterator();
        HttpConnection localHttpConnection;
        do
        {
          if (!(localIterator.hasNext()))
            break label50;
          localHttpConnection = (HttpConnection)localIterator.next();
        }
        while (localHttpConnection.isOpen());
        localIterator.remove();
        label50: deleteConnection(localHttpConnection);
      }
      finally
      {
        monitorexit;
      }
    }

    public void deleteLeastUsedConnection()
    {
      monitorenter;
      try
      {
        HttpConnection localHttpConnection = (HttpConnection)this.freeConnections.removeFirst();
        if (localHttpConnection != null)
          deleteConnection(localHttpConnection);
        do
          return;
        while (!(MultiThreadedHttpConnectionManager.LOG.isDebugEnabled()));
      }
      finally
      {
        monitorexit;
      }
    }

    public void freeConnection(HttpConnection paramHttpConnection)
    {
      HostConfiguration localHostConfiguration = this.this$0.configurationForConnection(paramHttpConnection);
      if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
        MultiThreadedHttpConnectionManager.LOG.debug("Freeing connection, hostConfig=" + localHostConfiguration);
      monitorenter;
      try
      {
        if (this.this$0.shutdown)
        {
          paramHttpConnection.close();
          monitorexit;
          return;
        }
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = getHostPool(localHostConfiguration, true);
        localHostConnectionPool.freeConnections.add(paramHttpConnection);
        if (localHostConnectionPool.numConnections == 0)
        {
          MultiThreadedHttpConnectionManager.LOG.error("Host connection pool not found, hostConfig=" + localHostConfiguration);
          localHostConnectionPool.numConnections = 1;
        }
        this.freeConnections.add(paramHttpConnection);
        MultiThreadedHttpConnectionManager.access$1300((MultiThreadedHttpConnectionManager.HttpConnectionWithReference)paramHttpConnection);
        if (this.numConnections == 0)
        {
          MultiThreadedHttpConnectionManager.LOG.error("Host connection pool not found, hostConfig=" + localHostConfiguration);
          this.numConnections = 1;
        }
        this.idleConnectionHandler.add(paramHttpConnection);
        notifyWaitingThread(localHostConnectionPool);
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public HttpConnection getFreeConnection(HostConfiguration paramHostConfiguration)
    {
      monitorenter;
      MultiThreadedHttpConnectionManager.HttpConnectionWithReference localHttpConnectionWithReference = null;
      try
      {
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = getHostPool(paramHostConfiguration, false);
        if ((localHostConnectionPool != null) && (localHostConnectionPool.freeConnections.size() > 0))
        {
          localHttpConnectionWithReference = (MultiThreadedHttpConnectionManager.HttpConnectionWithReference)localHostConnectionPool.freeConnections.removeLast();
          this.freeConnections.remove(localHttpConnectionWithReference);
          MultiThreadedHttpConnectionManager.access$900(localHttpConnectionWithReference, paramHostConfiguration, this);
          if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
            MultiThreadedHttpConnectionManager.LOG.debug("Getting free connection, hostConfig=" + paramHostConfiguration);
          this.idleConnectionHandler.remove(localHttpConnectionWithReference);
        }
        do
          return localHttpConnectionWithReference;
        while (!(MultiThreadedHttpConnectionManager.LOG.isDebugEnabled()));
      }
      finally
      {
        monitorexit;
      }
    }

    public MultiThreadedHttpConnectionManager.HostConnectionPool getHostPool(HostConfiguration paramHostConfiguration, boolean paramBoolean)
    {
      monitorenter;
      try
      {
        MultiThreadedHttpConnectionManager.LOG.trace("enter HttpConnectionManager.ConnectionPool.getHostPool(HostConfiguration)");
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = (MultiThreadedHttpConnectionManager.HostConnectionPool)this.mapHosts.get(paramHostConfiguration);
        if ((localHostConnectionPool == null) && (paramBoolean))
        {
          localHostConnectionPool = new MultiThreadedHttpConnectionManager.HostConnectionPool(null);
          localHostConnectionPool.hostConfiguration = paramHostConfiguration;
          this.mapHosts.put(paramHostConfiguration, localHostConnectionPool);
        }
        monitorexit;
        return localHostConnectionPool;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public void handleLostConnection(HostConfiguration paramHostConfiguration)
    {
      monitorenter;
      try
      {
        MultiThreadedHttpConnectionManager.HostConnectionPool localHostConnectionPool = getHostPool(paramHostConfiguration, true);
        localHostConnectionPool.numConnections -= 1;
        if ((localHostConnectionPool.numConnections == 0) && (localHostConnectionPool.waitingThreads.isEmpty()))
          this.mapHosts.remove(paramHostConfiguration);
        this.numConnections -= 1;
        notifyWaitingThread(paramHostConfiguration);
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public void notifyWaitingThread(HostConfiguration paramHostConfiguration)
    {
      monitorenter;
      try
      {
        notifyWaitingThread(getHostPool(paramHostConfiguration, true));
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    public void notifyWaitingThread(MultiThreadedHttpConnectionManager.HostConnectionPool paramHostConnectionPool)
    {
      monitorenter;
      MultiThreadedHttpConnectionManager.WaitingThread localWaitingThread = null;
      while (true)
      {
        try
        {
          if (paramHostConnectionPool.waitingThreads.size() > 0)
          {
            if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
              MultiThreadedHttpConnectionManager.LOG.debug("Notifying thread waiting on host pool, hostConfig=" + paramHostConnectionPool.hostConfiguration);
            localWaitingThread = (MultiThreadedHttpConnectionManager.WaitingThread)paramHostConnectionPool.waitingThreads.removeFirst();
            this.waitingThreads.remove(localWaitingThread);
            if (localWaitingThread != null)
            {
              localWaitingThread.interruptedByConnectionPool = true;
              localWaitingThread.thread.interrupt();
            }
            return;
          }
          if (this.waitingThreads.size() <= 0)
            break label157;
          if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
            MultiThreadedHttpConnectionManager.LOG.debug("No-one waiting on host pool, notifying next waiting thread.");
          localWaitingThread = (MultiThreadedHttpConnectionManager.WaitingThread)this.waitingThreads.removeFirst();
        }
        finally
        {
          monitorexit;
        }
        label157: if (!(MultiThreadedHttpConnectionManager.LOG.isDebugEnabled()))
          continue;
        MultiThreadedHttpConnectionManager.LOG.debug("Notifying no-one, there are no waiting threads");
      }
    }

    public void shutdown()
    {
      monitorenter;
      HttpConnection localHttpConnection;
      try
      {
        Iterator localIterator1 = this.freeConnections.iterator();
        if (!(localIterator1.hasNext()))
          break label49;
        localHttpConnection = (HttpConnection)localIterator1.next();
        localIterator1.remove();
      }
      finally
      {
        monitorexit;
      }
      label49: MultiThreadedHttpConnectionManager.access$600(this);
      Iterator localIterator2 = this.waitingThreads.iterator();
      while (localIterator2.hasNext())
      {
        MultiThreadedHttpConnectionManager.WaitingThread localWaitingThread = (MultiThreadedHttpConnectionManager.WaitingThread)localIterator2.next();
        localIterator2.remove();
        localWaitingThread.interruptedByConnectionPool = true;
        localWaitingThread.thread.interrupt();
      }
      this.mapHosts.clear();
      this.idleConnectionHandler.removeAll();
      monitorexit;
    }
  }

  private static class ConnectionSource
  {
    public MultiThreadedHttpConnectionManager.ConnectionPool connectionPool;
    public HostConfiguration hostConfiguration;

    private ConnectionSource()
    {
    }

    ConnectionSource(MultiThreadedHttpConnectionManager.1 param1)
    {
    }
  }

  private static class HostConnectionPool
  {
    public LinkedList freeConnections;
    public HostConfiguration hostConfiguration;
    public int numConnections;
    public LinkedList waitingThreads;

    private HostConnectionPool()
    {
      this.freeConnections = new LinkedList();
      this.waitingThreads = new LinkedList();
      this.numConnections = 0;
    }

    HostConnectionPool(MultiThreadedHttpConnectionManager.1 param1)
    {
    }
  }

  private static class HttpConnectionAdapter extends HttpConnection
  {
    private HttpConnection wrappedConnection;

    public HttpConnectionAdapter(HttpConnection paramHttpConnection)
    {
      super(paramHttpConnection.getHost(), paramHttpConnection.getPort(), paramHttpConnection.getProtocol());
      this.wrappedConnection = paramHttpConnection;
    }

    public void close()
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.close();
    }

    public boolean closeIfStale()
      throws IOException
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.closeIfStale(); ; bool = false)
        return bool;
    }

    public void flushRequestOutputStream()
      throws IOException
    {
      if (hasConnection())
      {
        this.wrappedConnection.flushRequestOutputStream();
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public String getHost()
    {
      if (hasConnection());
      for (String str = this.wrappedConnection.getHost(); ; str = null)
        return str;
    }

    public HttpConnectionManager getHttpConnectionManager()
    {
      if (hasConnection());
      for (HttpConnectionManager localHttpConnectionManager = this.wrappedConnection.getHttpConnectionManager(); ; localHttpConnectionManager = null)
        return localHttpConnectionManager;
    }

    public InputStream getLastResponseInputStream()
    {
      if (hasConnection());
      for (InputStream localInputStream = this.wrappedConnection.getLastResponseInputStream(); ; localInputStream = null)
        return localInputStream;
    }

    public InetAddress getLocalAddress()
    {
      if (hasConnection());
      for (InetAddress localInetAddress = this.wrappedConnection.getLocalAddress(); ; localInetAddress = null)
        return localInetAddress;
    }

    public HttpConnectionParams getParams()
    {
      if (hasConnection())
        return this.wrappedConnection.getParams();
      throw new IllegalStateException("Connection has been released");
    }

    public int getPort()
    {
      if (hasConnection());
      for (int i = this.wrappedConnection.getPort(); ; i = -1)
        return i;
    }

    public Protocol getProtocol()
    {
      if (hasConnection());
      for (Protocol localProtocol = this.wrappedConnection.getProtocol(); ; localProtocol = null)
        return localProtocol;
    }

    public String getProxyHost()
    {
      if (hasConnection());
      for (String str = this.wrappedConnection.getProxyHost(); ; str = null)
        return str;
    }

    public int getProxyPort()
    {
      if (hasConnection());
      for (int i = this.wrappedConnection.getProxyPort(); ; i = -1)
        return i;
    }

    public OutputStream getRequestOutputStream()
      throws IOException, IllegalStateException
    {
      if (hasConnection());
      for (OutputStream localOutputStream = this.wrappedConnection.getRequestOutputStream(); ; localOutputStream = null)
        return localOutputStream;
    }

    public InputStream getResponseInputStream()
      throws IOException, IllegalStateException
    {
      if (hasConnection());
      for (InputStream localInputStream = this.wrappedConnection.getResponseInputStream(); ; localInputStream = null)
        return localInputStream;
    }

    public int getSendBufferSize()
      throws SocketException
    {
      if (hasConnection())
        return this.wrappedConnection.getSendBufferSize();
      throw new IllegalStateException("Connection has been released");
    }

    public int getSoTimeout()
      throws SocketException
    {
      if (hasConnection())
        return this.wrappedConnection.getSoTimeout();
      throw new IllegalStateException("Connection has been released");
    }

    public String getVirtualHost()
    {
      if (hasConnection())
        return this.wrappedConnection.getVirtualHost();
      throw new IllegalStateException("Connection has been released");
    }

    HttpConnection getWrappedConnection()
    {
      return this.wrappedConnection;
    }

    protected boolean hasConnection()
    {
      if (this.wrappedConnection != null);
      for (int i = 1; ; i = 0)
        return i;
    }

    public boolean isOpen()
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isOpen(); ; bool = false)
        return bool;
    }

    public boolean isProxied()
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isProxied(); ; bool = false)
        return bool;
    }

    public boolean isResponseAvailable()
      throws IOException
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isResponseAvailable(); ; bool = false)
        return bool;
    }

    public boolean isResponseAvailable(int paramInt)
      throws IOException
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isResponseAvailable(paramInt); ; bool = false)
        return bool;
    }

    public boolean isSecure()
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isSecure(); ; bool = false)
        return bool;
    }

    public boolean isStaleCheckingEnabled()
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isStaleCheckingEnabled(); ; bool = false)
        return bool;
    }

    public boolean isTransparent()
    {
      if (hasConnection());
      for (boolean bool = this.wrappedConnection.isTransparent(); ; bool = false)
        return bool;
    }

    public void open()
      throws IOException
    {
      if (hasConnection())
      {
        this.wrappedConnection.open();
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void print(String paramString)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.print(paramString);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void print(String paramString1, String paramString2)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.print(paramString1, paramString2);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void printLine()
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.printLine();
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void printLine(String paramString)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.printLine(paramString);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void printLine(String paramString1, String paramString2)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.printLine(paramString1, paramString2);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public String readLine()
      throws IOException, IllegalStateException
    {
      if (hasConnection())
        return this.wrappedConnection.readLine();
      throw new IllegalStateException("Connection has been released");
    }

    public String readLine(String paramString)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
        return this.wrappedConnection.readLine(paramString);
      throw new IllegalStateException("Connection has been released");
    }

    public void releaseConnection()
    {
      if ((isLocked()) || (!(hasConnection())))
        return;
      HttpConnection localHttpConnection = this.wrappedConnection;
      this.wrappedConnection = null;
      localHttpConnection.releaseConnection();
    }

    public void setConnectionTimeout(int paramInt)
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setConnectionTimeout(paramInt);
    }

    public void setHost(String paramString)
      throws IllegalStateException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setHost(paramString);
    }

    public void setHttpConnectionManager(HttpConnectionManager paramHttpConnectionManager)
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setHttpConnectionManager(paramHttpConnectionManager);
    }

    public void setLastResponseInputStream(InputStream paramInputStream)
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setLastResponseInputStream(paramInputStream);
    }

    public void setLocalAddress(InetAddress paramInetAddress)
    {
      if (hasConnection())
      {
        this.wrappedConnection.setLocalAddress(paramInetAddress);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void setParams(HttpConnectionParams paramHttpConnectionParams)
    {
      if (hasConnection())
      {
        this.wrappedConnection.setParams(paramHttpConnectionParams);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void setPort(int paramInt)
      throws IllegalStateException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setPort(paramInt);
    }

    public void setProtocol(Protocol paramProtocol)
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setProtocol(paramProtocol);
    }

    public void setProxyHost(String paramString)
      throws IllegalStateException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setProxyHost(paramString);
    }

    public void setProxyPort(int paramInt)
      throws IllegalStateException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setProxyPort(paramInt);
    }

    public void setSendBufferSize(int paramInt)
      throws SocketException
    {
      if (hasConnection())
      {
        this.wrappedConnection.setSendBufferSize(paramInt);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void setSoTimeout(int paramInt)
      throws SocketException, IllegalStateException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.setSoTimeout(paramInt);
    }

    public void setSocketTimeout(int paramInt)
      throws SocketException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.setSocketTimeout(paramInt);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void setStaleCheckingEnabled(boolean paramBoolean)
    {
      if (hasConnection())
      {
        this.wrappedConnection.setStaleCheckingEnabled(paramBoolean);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void setVirtualHost(String paramString)
      throws IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.setVirtualHost(paramString);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void shutdownOutput()
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.shutdownOutput();
    }

    public void tunnelCreated()
      throws IllegalStateException, IOException
    {
      if (!(hasConnection()))
        return;
      this.wrappedConnection.tunnelCreated();
    }

    public void write(byte[] paramArrayOfByte)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.write(paramArrayOfByte);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void write(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.write(paramArrayOfByte, paramInt1, paramInt2);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void writeLine()
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.writeLine();
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }

    public void writeLine(byte[] paramArrayOfByte)
      throws IOException, IllegalStateException
    {
      if (hasConnection())
      {
        this.wrappedConnection.writeLine(paramArrayOfByte);
        return;
      }
      throw new IllegalStateException("Connection has been released");
    }
  }

  private static class HttpConnectionWithReference extends HttpConnection
  {
    public WeakReference reference = new WeakReference(this, MultiThreadedHttpConnectionManager.REFERENCE_QUEUE);

    public HttpConnectionWithReference(HostConfiguration paramHostConfiguration)
    {
      super(paramHostConfiguration);
    }
  }

  private static class ReferenceQueueThread extends Thread
  {
    private volatile boolean shutdown = false;

    public ReferenceQueueThread()
    {
      setDaemon(true);
      setName("MultiThreadedHttpConnectionManager cleanup");
    }

    private void handleReference(Reference paramReference)
    {
      synchronized (MultiThreadedHttpConnectionManager.REFERENCE_TO_CONNECTION_SOURCE)
      {
        MultiThreadedHttpConnectionManager.ConnectionSource localConnectionSource = (MultiThreadedHttpConnectionManager.ConnectionSource)MultiThreadedHttpConnectionManager.REFERENCE_TO_CONNECTION_SOURCE.remove(paramReference);
        if (localConnectionSource != null)
        {
          if (MultiThreadedHttpConnectionManager.LOG.isDebugEnabled())
            MultiThreadedHttpConnectionManager.LOG.debug("Connection reclaimed by garbage collector, hostConfig=" + localConnectionSource.hostConfiguration);
          localConnectionSource.connectionPool.handleLostConnection(localConnectionSource.hostConfiguration);
        }
        return;
      }
    }

    public void run()
    {
      while (!(this.shutdown))
        try
        {
          Reference localReference = MultiThreadedHttpConnectionManager.REFERENCE_QUEUE.remove();
          if (localReference != null);
          handleReference(localReference);
        }
        catch (InterruptedException localInterruptedException)
        {
          MultiThreadedHttpConnectionManager.LOG.debug("ReferenceQueueThread interrupted", localInterruptedException);
        }
    }

    public void shutdown()
    {
      this.shutdown = true;
      interrupt();
    }
  }

  private static class WaitingThread
  {
    public MultiThreadedHttpConnectionManager.HostConnectionPool hostConnectionPool;
    public boolean interruptedByConnectionPool;
    public Thread thread;

    private WaitingThread()
    {
      this.interruptedByConnectionPool = false;
    }

    WaitingThread(MultiThreadedHttpConnectionManager.1 param1)
    {
    }
  }
}

/* Location:           E:\Desktop\Android\wordstd\classes_dex2jar.jar
 * Qualified Name:     org.apache.commons.httpclient.MultiThreadedHttpConnectionManager
 * JD-Core Version:    0.5.3
 */